#ifndef MEMORY_H
#define MEMORY_H

#include"address_pool.h"

//定义一个LRU的地址内存最小单元
const int MAX_LRU_BLOCK_SIZE=10;//最大数量
struct LRU_Unit{
    int address;//起始地址
    int size;//大小
    int time;//未被使用的时间
    LRU_Unit(int a=0,int s=0,int t=0):address(a),size(s),time(t){}
};
enum AddressPoolType
{
    USER,
    KERNEL
};
class MemoryManager
{
public:
    int totalMemory;//可管理内存容量
    AddressPool kernelPhysical;//内核物理地址池
    AddressPool userPhysical;//用户物理地址池
    AddressPool kernelVirtual;//内核虚拟地址

    //least recently used算法
    LRU_Unit frame[MAX_LRU_BLOCK_SIZE];//lru单元数组
    int frame_size;//实际单元数量

    MemoryManager();
    void initialize();//初始化地址池
    int allocatePhysicalPages(enum AddressPoolType type,const int count);//从type类型物理地址池分配count个连续的页，成功返回起始地址，失败返回0
    void releasePhysicalPages(enum AddressPoolType type,const int startAddress,const int count);//释放从地址开始的count个物理页
    int getTotalMemory();//获取内存总容量
    int allocatePages(enum AddressPoolType type,const int count);//页内存分配
    int allocateVirtualPages(enum AddressPoolType type,const int count);//虚拟页分配
    bool connectPhysicalVirtualPage(const int virtualAddress,const int physicalPageAddress);//建立虚拟页到物理页的联系
    int toPDE(const int virtualAddress);//计算页目录项的虚拟地址
    int toPTE(const int virtualAddress);//计算页表项的虚拟地址
    void releasePages(enum AddressPoolType type,const int virtualAddress,const int count);//页内存释放
    int virtualAddressToPhysicalAddress(int virtualAddress);//找到虚拟地址对应的物理地址
    void releaseVirtualPages(enum AddressPoolType type,const int virtualAddress,const int count);//释放虚拟页
    void openPageMechanism();// 开启分页机制
};

#endif